'''This file defines the interface for special effects.'''

from os.path import join
from pygame import image, rect, mixer
from audio  import *

image_list = {}

def load_image(file_name):
    '''Loads and returns an image from a file. This function keeps track of
    previously loaded images to avoid multiple instances of the exact same
    image.'''
    global image_list
    if not image_list.has_key(file_name):
        image_list[file_name] = image.load(file_name)
    return image_list[file_name]

class Effect:
    '''This class represents a special effect. In this game's context, a special
    effect is a non-solid animated sprite.'''
    def __init__(self, position, image_file, frame_range, frame_size, sound_file):
        '''The images that belong to the effect's animation sequence are defined
        by a "range of equally sized frames" within a single image file.
        Parameters:
            position    - screen position where the sprite will be positioned.
            image_file  - The image file which contains the animation frames.
            frame_range - A sequence of frames that belong to this sprite's
                animation.
            frame_size  - This class assumes equal frame size for all frames
                in the animation sequence. This parameter is the width and
                height of one frame.
            sound_file  - A sound to be played when the sprite is spawned.'''
        self.position = rect.Rect(position, frame_size)
        self.position.center = position
        self.image    = load_image(image_file)
        self.sound    = load_sound(sound_file)
        self.frame    = -1
        self.destroy  = False

        self.frames = []
        w = self.image.get_width()/frame_size[0]
        for x in frame_range:
            self.frames.append(rect.Rect(((x%w)*frame_size[0],
                                          (x/w)*frame_size[1]),
                                          frame_size)
            )

    def get_rect(self):
        return self.position

    def draw(self, surface):
        surface.blit(self.image, self.position, self.frames[self.frame])

    def update(self):
        '''This update's the effect's displayed image or prepares it to be
        destroyed by the game's engine.'''
        self.frame += 1
        if self.frame >= len(self.frames):
            self.destroy = True
    
class Fireball_Effect(Effect):
    def __init__(self, position):
        Effect.__init__(self, position, join("data", "images", "explosion 3.png"), range(0, 10), (64,64), join("data", "sounds", "boom.wav"))

#class Fireball_MagicCircle(Effect):
#    def __init__(self, position):
#        Effect.__init__(self, position, join("data", "images", "magic_circles.png"), range(0, 5), (48,48), None)

class E_Bolt_Effect(Effect):
    def __init__(self, position):
        Effect.__init__(self, position, join("data", "images", "explosion 3.png"), range(10, 20), (64,64), join("data", "sounds", "zap3.wav"))

class MMissile_Effect(Effect):
    def __init__(self, position):
        Effect.__init__(self, position, join("data", "images", "explosion 3.png"), range(20, 30), (64,64), join("data", "sounds", "boom.wav"))

